package com.lc.pda.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lc.pda.dao.WmsReceiptMapper;
import com.lc.pda.dto.AgvDTO;
import com.lc.pda.dto.GroupReceiptDTO;
import com.lc.pda.entity.WmsInventory;
import com.lc.pda.entity.WmsReceipt;
import com.lc.pda.entity.WmsReceiptDetail;
import com.lc.pda.entity.WmsTask;
import com.lc.pda.service.WmsInventoryService;
import com.lc.pda.service.WmsReceiptDetailService;
import com.lc.pda.service.WmsReceiptService;
import com.lc.pda.service.WmsTaskService;
import com.lc.pda.util.Enums;
import com.lc.pda.util.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 入库单主表 服务实现类
 * </p>
 *
 * @author zww
 * @since 2023-07-06
 */
@Slf4j
@Service
public class WmsReceiptServiceImpl extends ServiceImpl<WmsReceiptMapper, WmsReceipt> implements WmsReceiptService {

    @Resource
    private WmsReceiptDetailService receiptDetailService;
    @Resource
    private WmsInventoryService inventoryService;
    @Resource
    private WmsTaskService taskService;

    @Override
    public List<WmsReceipt> getReceipt(String receiptCode) {
        List<WmsReceipt> list = list(Wrappers.<WmsReceipt>lambdaQuery()
                .eq(StringUtils.isNotEmpty(receiptCode), WmsReceipt::getReceiptCode, receiptCode)
                .lt(WmsReceipt::getReceiptStatus, Enums.ReceiptStatusEnum.finish.getStatus())
        );
        for (WmsReceipt receipt : list) {
            List<WmsReceiptDetail> details = receiptDetailService.list(Wrappers.<WmsReceiptDetail>lambdaQuery()
                    .eq(WmsReceiptDetail::getReceiptId, receipt.getReceiptId())
                    .lt(WmsReceiptDetail::getReceiptStatus, Enums.ReceiptStatusEnum.finish.getStatus())
            );
            receipt.setDetails(details);
        }
        return list;
    }

    @Override
    @Transactional
    public RestResult groupReceipt(GroupReceiptDTO groupReceiptDTO) {
        Enums.ReceiptTypeEnum enumByType = null;
        try {
            enumByType = Enums.ReceiptTypeEnum.getEnumByType(groupReceiptDTO.getReceiptType());
        } catch (Exception e) {
            return RestResult.error("入库类型不能为空！");
        }
        switch (enumByType) {
            case raw_receipt:
                return rawReceiptByPda(groupReceiptDTO);
            case pro_receipt:
                return rawReceiptByPda(groupReceiptDTO);
            case raw_return:
                //回库任务只需传递托盘号即可
                return rawReturnByPda(groupReceiptDTO);
            default:
                return RestResult.error("无此类型组盘操作！");
        }
    }

    private RestResult rawReturnByPda(GroupReceiptDTO groupReceiptDTO) {
        List<WmsInventory> list = inventoryService.list(Wrappers.<WmsInventory>lambdaQuery().eq(WmsInventory::getTrayCode, groupReceiptDTO.getTrayCode()));
        if (list.isEmpty()) {
            return RestResult.error("无库存，无需回库！");
        }
        //取第一条
        WmsInventory wmsInventory = list.get(0);
        WmsTask task = new WmsTask()
                .setTaskId(IdWorker.getIdStr())
                .setStockId(wmsInventory.getInventoryId())
                .setTaskType(Enums.TaskTypeEnum.in.getType())
                .setLotNo(wmsInventory.getLotCode())
                .setMaterialCode(wmsInventory.getMaterialCode())
                .setMaterialName(wmsInventory.getMaterialName())
                .setMaterialSpec(wmsInventory.getSpecification())
                .setMaterialUnit(wmsInventory.getUnitCode())
                .setTrayCode(groupReceiptDTO.getTrayCode())
                .setWarehouseCode(wmsInventory.getWarehouseCode())
                .setPlanQty(wmsInventory.getQty())
                .setTaskStatus(Enums.TaskStatusEnum.init.getStatus())
                .setLabelNo(groupReceiptDTO.getBarCode())
                .setCreateBy(groupReceiptDTO.getOperator())
                .setCreateTime(LocalDateTime.now());
        taskService.save(task);
        return RestResult.success("回库操作完成！");
    }

    private RestResult rawReceiptByPda(GroupReceiptDTO groupReceiptDTO) {
        BigDecimal receiptQty = new BigDecimal(groupReceiptDTO.getReceiptQty());
        if (BigDecimal.ZERO.compareTo(receiptQty) >= 0) {
            return RestResult.error("入库数量不能为空或零！");
        }
        WmsReceiptDetail wmsReceiptDetail = receiptDetailService.getOne(
                Wrappers.<WmsReceiptDetail>lambdaQuery().eq(WmsReceiptDetail::getReceiptdetailId, groupReceiptDTO.getReceiptdetailId())
                        .lt(WmsReceiptDetail::getReceiptStatus, Enums.ReceiptStatusEnum.finish.getStatus())
        );
        if (wmsReceiptDetail == null) {
            return RestResult.error("无此入库单明细，或入库单明细已完成！");
        }
        //todo 判断托盘重复
        //生成库存
        WmsInventory wmsInventory = new WmsInventory()
                .setInventoryId(IdWorker.getIdStr())
                .setMaterialCode(wmsReceiptDetail.getMaterialCode())
                .setMaterialName(wmsReceiptDetail.getMaterialName())
                .setSpecification(wmsReceiptDetail.getMaterialSpec())
                .setUnitCode(wmsReceiptDetail.getMaterialUnit())
                .setWarehouseCode(wmsReceiptDetail.getWarehouseCode())
                .setLotCode(wmsReceiptDetail.getLotNo())
                .setTrayCode(groupReceiptDTO.getTrayCode())
                .setBarCode(groupReceiptDTO.getBarCode())
                .setStoreType(groupReceiptDTO.getStoreType())
                .setQty(receiptQty)
                .setCreateBy(groupReceiptDTO.getOperator())
                .setCreateTime(LocalDateTime.now());
        inventoryService.save(wmsInventory);
        //生成入库任务
        WmsTask task = new WmsTask()
                .setTaskId(IdWorker.getIdStr())
                .setOrderCode(wmsReceiptDetail.getReceiptCode())
                .setStockId(wmsInventory.getInventoryId())
                .setSourceId(wmsReceiptDetail.getReceiptdetailId())
                .setTaskType(Enums.TaskTypeEnum.in.getType())
                .setLotNo(wmsReceiptDetail.getLotNo())
                .setMaterialCode(wmsReceiptDetail.getMaterialCode())
                .setMaterialName(wmsReceiptDetail.getMaterialName())
                .setMaterialSpec(wmsReceiptDetail.getMaterialSpec())
                .setMaterialUnit(wmsReceiptDetail.getMaterialUnit())
                .setTrayCode(groupReceiptDTO.getTrayCode())
                .setWarehouseCode(wmsReceiptDetail.getWarehouseCode())
                .setPlanQty(receiptQty)
                .setTaskStatus(Enums.TaskStatusEnum.init.getStatus())
                .setLabelNo(groupReceiptDTO.getBarCode())
                .setLifnr(wmsReceiptDetail.getLifnr())
                .setCreateBy(groupReceiptDTO.getOperator())
                .setCreateTime(LocalDateTime.now());
        taskService.save(task);

        if (wmsReceiptDetail.getRealQty() != null) {
            wmsReceiptDetail.setRealQty(wmsReceiptDetail.getRealQty().add(receiptQty));
        } else {
            wmsReceiptDetail.setRealQty(receiptQty);
        }
        if (wmsReceiptDetail.getRealQty().compareTo(wmsReceiptDetail.getPlanQty()) >= 0) {
            wmsReceiptDetail.setReceiptStatus(Enums.ReceiptStatusEnum.finish.getStatus());
        } else {
            wmsReceiptDetail.setReceiptStatus(Enums.ReceiptStatusEnum.ing.getStatus());
        }
        receiptDetailService.updateById(wmsReceiptDetail);
        return RestResult.success("组盘成功！");
    }


    @Override
    public RestResult callAgv(AgvDTO agvDTO) {
        //todo 调度发送给AGV信息
        return RestResult.success("调度任务下发成功");
    }
}
